3.2.8 跨域和 HTTP

跨域

跨域是指一个域下的文档或者脚本试图去请求另一个域下的资源.

什么是同源策略

同源策略是浏览器最核心也最按基本的安全功能,缺少了同源策略,浏览器很容易受到xss、csfr等攻击.

  • 同源: 网络协议 域名 端口 三者相同 .
  • 同源策略限制一下几种行为:
      1. cookie localstorage 和 indexdb 无法读取
      1. dom 和 js对象无法获得
      1. ajax 请求不能发送

跨域解决方案

  • 1、 通过jsonp跨域

  • 2、 document.domain + iframe跨域

  • 3、 location.hash + iframe

  • 4、 window.name + iframe跨域

  • 5、 postMessage跨域

  • 6、 跨域资源共享(CORS)

  • 7、 nginx代理跨域

  • 8、 nodejs中间件代理跨域

  • 9、 WebSocket协议跨域

  • 参考:

是服务器写入浏览器的一小段信息,只有同源的网页才能共享。
但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。

举例来说,
A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,
那么只要设置相同的document.domain,两个网页就可以共享Cookie。

注意,这种方法只适用于 Cookie 和 iframe 窗口,
LocalStorage 和 IndexDB 无法通过这种方法,
规避同源政策,而要使用下文介绍的PostMessage API。

对于完全不同源的网站,目前有三种方法,可以解决跨域窗口的通信问题。

  • 片段识别符(fragment identifier)
  • window.name
  • 跨文档通信API(Cross-document messaging)

1 片段识别符

片段标识符(fragment identifier)指的是,URL的#号后面的部分,
比如http://example.com/x.html#fragment的#fragment。如果只是改变片段标识符,页面不会重新刷新。

父窗口可以把信息,写入子窗口的片段标识符。

2.window.name

浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。

父窗口先打开一个子窗口,载入一个不同源的网页,该网页将信息写入window.name属性。

3 window.postMessage

上面两种方法都属于破解,HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging)。

这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。

举例来说,父窗口http://aaa.com向子窗口http://bbb.com发消息,调用postMessage方法就可以了。

var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');
1
2

postMessage方法的第一个参数是具体的信息内容,
第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送。

子窗口向父窗口发送消息的写法类似。

window.opener.postMessage('Nice to see you', 'http://aaa.com');
1
  • 父窗口和子窗口都可以通过message事件,监听对方的消息。
window.addEventListener('message', function(e) {
  console.log(e.data);
},false);
1
2
3
  • message事件的事件对象event,提供以下三个属性。
event.source:发送消息的窗口
event.origin: 消息发向的网址
event.data: 消息内容
1
2
3

AJAX

同源政策规定,AJAX请求只能发给同源的网址,否则就报错。

除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制。

JSONP: 它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;  JSONP只支持GET请求,
WebSocket: WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信
CORS: 跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法
1
2
3

CORS需要浏览器和服务器同时支持。

  • 浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

简单请求

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,
请注意,该术语并不属于 Fetch (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

使用下列方法之一:

GET
HEAD
POST

Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (需要注意额外的限制)
DPR
Downlink
Save-Data
Viewport-Width
Width

Content-Type 的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded

请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。
请求中没有使用 ReadableStream 对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

预检请求

“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。
"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

当请求满足下述任一条件时,即应首先发送预检请求:

使用了下面任一 HTTP 方法:

PUT
DELETE
CONNECT
OPTIONS
TRACE
PATCH

人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type (but note the additional requirements below)
DPR
Downlink
Save-Data
Viewport-Width
Width

 Content-Type 的值不属于下列之一:
application/x-www-form-urlencoded
multipart/form-data
text/plain

请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
请求中使用了ReadableStream对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

HTTP 请求首部字段

Origin 首部字段表明预检请求或实际请求的源站。

Origin: <origin>

Access-Control-Request-Method: <method>

Access-Control-Request-Headers: <field-name>[, <field-name>]*
1
2
3
4
5
6
7

HTTP 响应首部字段

Access-Control-Allow-Origin: <origin> | *
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
Access-Control-Max-Age: <delta-seconds>
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: <method>[, <method>]*
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
1
2
3
4
5
6

http 协议

Hyper Text Transfer Protocol(超文本传输协议)

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

  • 下面是一些常见的Content-Type字段的值。这些数据类型总称为MIME type
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml
1
2
3
4
5
6
7
8
9
10
11
12
  • MIME type还可以在尾部使用分号,添加参数。
Content-Type: text/html; charset=utf-8
1
  • MIME type不仅用在HTTP协议,还可以用在其他地方,比如HTML网页。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- 等同于 -->
<meta charset="utf-8" /> 
1
2
3
  • 缺点
    • HTTP/1.0 版的主要缺点是,每个TCP连接只能发送一个请求。发送数据完毕,连接就关闭,如果还要请求其他资源,就必须再新建一个连接。

    • TCP连接的新建成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(slow start)。
      所以,HTTP 1.0版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。

    • 为了解决这个问题,有些浏览器在请求时,用了一个非标准的Connection字段。

Connection: keep-alive
1
  • http 状态值 ajax 的 readyState

    • 0 - (未初始化)还没有调用send()方法
    • 1 - (载入)已调用send()方法,正在发送请求
    • 2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
    • 3 - (交互)正在解析响应内容
    • 4 - (完成)响应内容解析完成,可以在客户端调用了
  • http 状态码

    1xx:请求收到,继续处理
    2xx:操作成功收到,分析、接受
    3xx:完成此请求必须进一步处理
    4xx:请求包含一个错误语法或不能完成
    5xx:服务器执行一个完全有效请求失
    
    1
    2
    3
    4
    5
    • 200, OK,访问正常
    • 301, Moved Permanently,永久移动
    • 302, Move temporarily,暂时移动
    • 304, Not Modified,未修改
    • 307, Temporary Redirect,暂时重定向
    • 401, Unauthorized,未授权
    • 403, Forbidden,禁止访问
    • 404, Not Found,未发现指定网址
    • 500, Internal Server Error,服务器发生错误

Https与Http

  • 1、https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。

  • 2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。

  • 3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。

  • 4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。

## TLS就是SSL的升级版

TLS比SSL更加标准化,更加安全

SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持

作用

(1) 窃听风险(eavesdropping):第三方可以获知通信内容。

(2) 篡改风险(tampering):第三方可以修改通信内容。

(3) 冒充风险(pretending):第三方可以冒充他人身份参与通信。

SSL/TLS协议是为了解决这三大风险而设计的,希望达到:

(1) 所有信息都是加密传播,第三方无法窃听。

(2) 具有校验机制,一旦被篡改,通信双方会立刻发现。

(3) 配备身份证书,防止身份被冒充。
1
2
3
4
5
6
7
8
9
10
11
12
13

SSL/TLS协议的基本思路是采用公钥(yao)加密法,

也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

  • 如何保证公钥不被篡改?

解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的

  • 公钥加密计算量太大,如何减少耗用的时间?

解决方法:每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。
由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。

SSL/TLS协议的基本过程是这样的:
(1) 客户端向服务器端索要并验证公钥。
(2) 双方协商生成"对话密钥"。
(3) 双方采用"对话密钥"进行加密通信。
上面过程的前两步,又称为"握手阶段"(handshake)。

握手阶段的详细过程

1.客户端发出请求(ClientHello

客户端主要向服务器提供以下信息。

(1) 支持的协议版本,比如TLS 1.0版。

(2) 一个客户端生成的随机数,稍后用于生成"对话密钥"。

(3) 支持的加密方法,比如RSA公钥加密。

(4) 支持的压缩方法。
1
2
3
4
5
6
7
8
9

2.服务器回应(SeverHello)

服务器的回应包含以下内容。

(1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。

(2) 一个服务器生成的随机数,稍后用于生成"对话密钥"。

(3) 确认使用的加密方法,比如RSA公钥加密。

(4) 服务器证书。
1
2
3
4
5
6
7
8
9

3.客户端回应

如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。

(1) 一个随机数。该随机数用服务器公钥加密,防止被窃听。

(2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
1
2
3
4
5
6
7

4.服务器的最后回应

服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。

(1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
1
2
3
4
5

https工作原理

1.你的浏览器请服务器发送建立连接消息,消息中包含加密算法,是使用的协议等。
2.服务器对你的浏览器回应一个消息,消息中包含证书信息,然后你可以对证书的真伪进行验证。
3.验证通过之后,如果一切都按预期(即服务器已经成功验证),浏览器开始发送交换(和同意)应该用于此会话的随机密钥。
4.服务器接收到到随机秘钥,然后开始进行数据交换。最终网页的内容安全地传输并显示在您的浏览器中。

客户端在使用 HTTPS 方式与 Web 服务器通信时有以下几个步骤,如图所示。

  • (1)客户使用 https 的 URL 访问 Web 服务器,要求与 Web 服务器建立 SSL 连接。

  • (2)Web 服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。

  • (3)客户端的浏览器与 Web 服务器开始协商 SSL 连接的安全等级,也就是信息加密的等级。

  • (4)客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。

  • (5)Web 服务器利用自己的私钥解密出会话密钥。

  • (6)Web 服务器利用会话密钥加密与客户端之间的通信。

电子证书有哪些部分组成?

主体部分包括:

版本号:
序列号:
签名算法标识符
认证机构的数字签名:
认证机构:
有效期限
公钥信息: 


1
2
3
4
5
6
7
8
9

https优缺点

  • (1)HTTPS 协议握手阶段比较费时,会使页面的加载时间延长近 50%,增加 10% 到 20% 的耗电;

  • (2)HTTPS 连接缓存不如 HTTP 高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;

  • (3)SSL 证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。

  • (4)SSL 证书通常需要绑定 IP,不能在同一 IP 上绑定多个域名,IPv4 资源不可能支撑这个消耗。

  • (5)HTTPS 协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。


作者:谁动了我的bug 原文:https://blog.csdn.net/qq_35393693/article/details/80282102

http2

  • 1.二进制协议:

HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为"帧"(frame):头信息帧和数据帧。

二进制协议的一个好处是,可以定义额外的帧

  • 2.多工: 双向的、实时的通信,就叫做多工(Multiplexing)。

HTTP/2 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了"队头堵塞"

  • 3.数据流

因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪个回应。

HTTP/2 将每个请求或回应的所有数据包,称为一个数据流(stream)。

每个数据流都有一个独一无二的编号。数据包发送的时候,都必须标记数据流ID,用来区分它属于哪个数据流。

另外还规定,客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数。

数据流发送到一半的时候,客户端和服务器都可以发送信号(RST_STREAM帧),取消这个数据流。

1.1版取消数据流的唯一方法,就是关闭TCP连接。这就是说,HTTP/2 可以取消某一次请求,同时保证TCP连接还打开着,可以被其他请求使用。

客户端还可以指定数据流的优先级。优先级越高,服务器就会越早回应。

  • 4.头信息压缩:

    • HTTP 协议不带有状态,每次请求都必须附上所有信息。
      所以,请求的很多字段都是重复的,比如Cookie和User Agent,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。
    • HTTP/2 对这一点做了优化,引入了头信息压缩机制(header compression)。
      一方面,头信息使用gzip或compress压缩后再发送;
      另一方面,客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,
      以后就不发送同样字段了,只发送索引号,这样就提高速度了。
  • 5.服务器推送

HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送(server push)

参考